package com.ms.qw.util;

import com.ms.qw.util.support.PropertyUnaryFunction;
import com.ms.qw.util.support.SumUnaryFunction;
import org.apache.commons.functor.UnaryFunction;
import org.apache.commons.functor.UnaryPredicate;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.math.BigDecimal;
import java.util.*;

public class ListUtil {

    public static BigDecimal sum(Collection list, String propertyName, UnaryPredicate predicate) {
        SumUnaryFunction sumUnaryFunction = new SumUnaryFunction(propertyName);
        apply(list, predicate, sumUnaryFunction);
        return sumUnaryFunction.getTotal();
    }
    public static void apply(Collection list, UnaryPredicate predicate, UnaryFunction function) {
        for (Object o : list) {
            if (predicate == null || predicate.test(o)) {
                function.evaluate(o);
            }
        }
    }
    public static Set columnAsSet(Collection list, String propertyName, UnaryPredicate predicate) {
        final Collection subList = new HashSet(list.size());
        return (Set) columnAsList(list, propertyName, predicate, subList);
    }

    public static <E> List<E> getSubList(Collection<E> list, UnaryPredicate predicate) {
        List subList = new ArrayList();
        for (Iterator iterator = list.iterator(); iterator.hasNext();) {
            Object o = iterator.next();
            if (predicate.test(o)) {
                subList.add(o);
            }
        }
        return subList;
    }

    public static <E> List<E> getSubList(List<E> list, final String propertyName, final Object propertyValue) {
        return getSubList(list, new UnaryPredicate(){
            @Override
            public boolean test(Object o) {
                BeanWrapper wrapper = new BeanWrapperImpl(o);
                return propertyValue.equals(wrapper.getPropertyValue(propertyName)) ;
            }
        }) ;
    }

    private static Collection columnAsList(Collection list, final String propertyName, UnaryPredicate predicate, final Collection subList) {
        PropertyUnaryFunction unaryFunction = new PropertyUnaryFunction(propertyName) {
            protected Object evaluate(Object bean, Object propertyValue) {
                subList.add(propertyValue);
                return null;
            }
        };
        apply(list, predicate, unaryFunction);
        return subList;
    }

}
